import el from '../utils/el'
import box from './box'
import curveElement from './curveElement'

/**
 * 生成音高元素的函数
 *
 * 此函数负责根据给定的音高布局对象生成与音高相关的各种元素，
 * 包括音调（step）、变音记号（accidental）、八度（octave）以及连音线等。
 * 它通过解构、判断和创建元素的方式来构建音高的视觉表示。
 *
 * @param {Object} pitchLayout - 包含音高及其相关布局信息的对象
 * @returns {Array} 返回一个数组，包含所有要渲染的元素
 */
export default function pitchElement(pitchLayout) {

  // 解构音高布局对象以获取各个布局部分
  const { pitch, stepLayout, accidentalLayout, octavesLayout,
          tieLayout, tieMode } = pitchLayout

  console.log("pitchElement-------pitchLayout-octavesLayout---", octavesLayout)

  // 定义音调元素的样式
  const sty1 = `
    font-family: ${stepLayout.family}
    font-size: ${stepLayout.size}
    text-anchor: middle
  `
  // 定义变音记号元素的样式
  const sty2 = `
    font-family: ${accidentalLayout.family}
    font-size: ${accidentalLayout.size}
    text-anchor: middle
  `

  /**
   * 判断是否显示连音线布局
   *
   * 此函数用于确定在给定的连音线布局对象下是否需要显示连音线布局它考虑了布局对象的存在性、当前是否处于连音模式
   * 以及连音线的类型和是否显示前一个连音线状态
   *
   * @param {Object} tieLayout - 连音线布局对象，包含连音信息和显示状态
   * @returns {boolean} 返回一个布尔值，指示是否应该显示连音线布局
   */
  const showTie = tieLayout => {
    // 当连音线布局对象不存在或连音模式为单个时，不显示连音线布局
    if (!tieLayout || tieMode === 'single') {
      return false
    }

    // 从连音线布局对象中提取连音信息
    const { tie } =  tieLayout

    // 当连音类型不是结束类型，或者当前连音线布局需要显示前一个连音线时，返回true
    return tie.type !== 'end' || tieLayout.showPrev
  }

  // 用于存储生成的元素的对象
  const elements = {}

  /**
   * 设置音符元素的颜色
   *
   * 此函数的目的是统一改变音符相关元素的填充颜色，以匹配音符的视觉呈现
   * 它首先改变基础音符步骤（step）的颜色，然后根据音符的变音记号（accidental）
   * 和八度（octave）情况，分别改变这些元素的颜色，以保持视觉上的一致性
   *
   * @param {string} color - 要设置的颜色值，表示为CSS颜色字符串
   */
  const setColor = color => {
    // 设置音符基础步骤的颜色
    elements.step.style.fill = color

    // 如果音符有变音记号，设置变音记号的颜色
    if (pitch.accidental) {
      elements.accidental.style.fill = color
    }

    // 如果音符有八度标记，设置所有八度标记的颜色
    if (pitch.octave) {
      elements.octaves.forEach(element => {
        element.style.fill = color
      })
    }
  }

  // 设置音符播放和停止时的颜色变化
  pitch.onplay = () => setColor('#b5c')
  pitch.onstop = () => setColor('black')

  // 创建并返回音高元素的集合
  return el.create('g', [
    // 创建音调
    el.assign(elements, 'step')
      .create('text', { ...stepLayout.cxby, style: sty1 }, pitch.step),

    // 如果音符有变音记号，创建变音记号元素
    pitch.accidental ?
      el.assign(elements, 'accidental')
        .create('text', { ...accidentalLayout.cxby, style: sty2 }, accidentalLayout.char) : [],

    // 如果音符有八度标记，创建八度标记元素
    pitch.octave ? octavesLayout.layouts.map(layout => {
      return el.push(elements, 'octaves')
           .create('circle', layout.circle)
    }) : [],

    // 根据是否显示连音线布局的判断，决定是否添加连音线元素
    showTie(tieLayout) ? curveElement(tieLayout) : []
  ])
}
